package main;

import session.Session;
import main.gui.CoreMessageFrame;
import configuration.Paths;

public class Core {

	/*
	 * The singleton instance of the Core class.
	 */
	private static Core instance;

	/*
	 * True if the core has been started up and has not yet been shut down.
	 */
	private static boolean active = false;

	/*
	 * True if developer wishes to view debug message window.
	 */
	private boolean debugModeOn;

	/*
	 * The window in which detailed debug messages are displayed.
	 */
	private CoreMessageFrame messageFrame;

	/**
	 * Creates a new application core.
	 * 
	 * @param debugModeOn
	 *            True if the user wishes to display the message frame for debug
	 *            purposes.
	 */
	private Core(boolean debugModeOn) {
		this.debugModeOn = debugModeOn;

		// If in debug mode, instantiate the core message frame object
		if (this.debugModeOn) {
			this.messageFrame = new CoreMessageFrame();
		}
	}

	/**
	 * The singleton accessor for the Core class.
	 * 
	 * @return Core The singleton instance of the application Core.
	 */
	public static Core getInstance() {
		if (instance == null) {
			// For now, the debug mode status is hard coded as true. Later,
			// it
			// may be loaded in as a configuration.
			instance = new Core(false);
		}
		return instance;
	}

	/**
	 * Logs a message in the core system.
	 * 
	 * @param source
	 *            The class name from which the message originated.
	 * @param message
	 *            The textual message.
	 */
	public void logMessage(String source, String message) {
		// If in debug mode, add the message to the core message frame
		if (debugModeOn) {
			String combinedMessage = source + ":\n>" + message;
			messageFrame.addMessage(combinedMessage);
		}
	}

	/**
	 * Logs a message in the core system.
	 * 
	 * @param source
	 *            The class name from which the message originated.
	 * @param message
	 *            The textual message.
	 * @param e
	 *            The exception that goes along with the message.
	 */
	public void logMessage(String source, String message, Exception e) {
		// Print the exception to console
		System.err.println(e);

		// If in debug mode, add the message to the core message frame
		if (debugModeOn) {
			String combinedMessage = source + ":\n>" + message;
			messageFrame.addMessage(combinedMessage);
		}
	}

	/**
	 * Starts up and initializes every necessary basic component.
	 */
	public void startup() {
		if (!Core.active) {
			// Load file paths
			Paths.setupPaths();
			
			// Display core message frame if debug mode is on
			if (debugModeOn) {
				this.messageFrame.setVisible(true);
			}

			// Make the Core active
			Core.active = true;
		}
	}

	/**
	 * Shuts down the core application and components.
	 */
	public void shutdown() {
		if (Core.active) {
			// Close the current project session
			Session.getInstance().closeProject();
			
			// Make the Core inactive
			Core.active = false;
		}
	}

	/**
	 * Accessor for debug mode status.
	 * 
	 * @return boolean True if debug mode is on.
	 */
	public boolean debugMode() {
		return this.debugModeOn;
	}

}
